package evolutionaryProblems;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import statistics.PopulationStatistics;
import beerAgent.BeerFitnessFunction;
import beerAgent.BeerParameters;
import beerAgent.BeerProblem;
import evolutionaryLoop.EvolutionaryLoop;
import evolutionaryLoop.EvolutionaryParameters;
import evolutionaryLoop.Population;
import flatlandAgent.FlatlandProblem;
import gui.GUIFrame;
import gui.GameModel;
import gui.LineChart;


public abstract class Problem<T extends EvolutionaryParameters> {
	
	protected T parameters; 
	protected EvolutionaryLoop evLoop;
	protected GUIFrame guiFrame; 
	protected LineChart lineChart;
	protected GameModel gameModel; 
	
//	public Problem(T parameters){
//		this.parameters = parameters; 
//	}
	
	public void startSimulation(){
		lineChart.emptyDataSet(); 
		evLoop = new EvolutionaryLoop(parameters, generatePopulation(), this); 
		evLoop.runLoop();
	}
	
	protected void emptyLineChart() {
		lineChart.emptyDataSet(); 
	}

	protected void initialise() {
		initParameters(); 
		initGUI(); 
	}

	protected abstract void initGUI();


	protected abstract void initParameters();
	
	public void pauseSimulation() {
		if (evLoop != null) {
			evLoop.setPause(true);
		}
	}

	public void continueSimulation() {
		if (evLoop != null) {
			evLoop.setPause(false);
			evLoop.runLoop();
		}
	}
	
	/**
	 * Stops the evolutionary loop and reset the phenotype list. 
	 */
	public void killSimulation(){
		if (evLoop != null) {
//			System.out.println("hallaballa");
			evLoop.kill(); 
			while (!evLoop.haveKilled()) {
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} 
			}
		}
		if (gameModel != null) {
			gameModel.resetPhenoypeList();
		}
	}
	
	/**
	 * Update the data in the line chart
	 */
	public void updateStatistics(PopulationStatistics statistics){
		if (lineChart != null) {
			lineChart.addMaxFit(statistics.getGeneration(), statistics.getBestFitness()); 
			lineChart.addAverageFit(statistics.getGeneration(), statistics.getAvgFitness()); 
			lineChart.addStandardDeviation(statistics.getGeneration(), statistics.getStandardDiviation());
		}
		if (gameModel != null) {
			gameModel.addPheontype(statistics.getBest(), statistics.getGeneration());
		}
	}


	protected abstract Population generatePopulation();
	
	public static void main(String[] args) {
		JFrame startFrame = new JFrame(); 
		
		JPanel startPanel = new JPanel();
		
		JButton flatlandButton = new JButton("Flatland Problem"); 
		flatlandButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				new FlatlandProblem(); 
			}
		});
		startPanel.add(flatlandButton); 
		
		JButton beerButton = new JButton("Beer Problem"); 
		beerButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				new BeerProblem(); 
			}
		});
		startPanel.add(beerButton); 
		
		startFrame.setContentPane(startPanel); 
		startFrame.setSize(250, 150); 
		startFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		startFrame.setVisible(true); 
	}
}
